using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using OpenComposite.Base.Designer;

namespace OpenComposite.EII.Designer.BUSView
{
	#region Abstract Class: BUSRoute : Base: Route
	public abstract class BUSRoute : Route
	{
		#region Initialization
		public BUSRoute()
		{
			init();
		}
		private void init()
		{
			this.BeginUpdate();

			_document = new BUSDocumentSymbol();
			_document.Location = GetDocumentLocation();
			_document.SizeChanged += new EventHandler(_document_SizeChanged);
			_document.Removed += new EventHandler(_document_Removed);
			this.Controls.Add(_document);

			Initialize();

			this.EndUpdate();
		}

		#endregion

		#region Public Members

		#region Properties
		// new
		public BUSDocumentSymbol Document
		{
			get { return _document; }
			set { _document = value; }
		}

		// override
		public override bool CanMove
		{
			get
			{
				return false;
			}
		}
		public override void Paint(System.Windows.Forms.PaintEventArgs pe)
		{
			base.Paint(pe);
			//if ( _document != null ) {
			//    _document.PaintBackground(pe);
			//    _document.Paint(pe);
			//}
		}

		public override void ReadXml(System.Xml.XmlReader reader)
		{
			return;
		}
		public override void WriteXml(System.Xml.XmlWriter writer)
		{
			return;
		}
		#endregion

		#endregion

		#region Protected Members

		#region Constants
		protected const int gap = 3;
		protected const int cBUSExtend = 150;
		#endregion

		#region Methods
		// abstract
		protected abstract Point GetDocumentLocation();
		protected abstract void Initialize();

		// virtual
		protected virtual void OnDocumentSizeChanged()
		{
		}

		// override
		protected override void OnLocationChanged(EventArgs e)
		{
			if ( this.Document != null )
				this.Document.Location = GetDocumentLocation();
			base.OnLocationChanged(e);
		}
		protected override void OnSizeChanged(EventArgs e)
		{
			if ( this.Document != null )
				this.Document.Location = GetDocumentLocation();
			base.OnSizeChanged(e);
		}
		protected override void OnRemoved(EventArgs e)
		{
			_isInOnRemoved = true;
			if ( this.Document != null )
				this.Document.Remove();
			base.OnRemoved(e);
			_isInOnRemoved = false;
		}
		protected override void OnVisibleChanged()
		{
			if ( this.Document != null )
				this.Document.Visible = this.Visible;
			base.OnVisibleChanged();
		}

		protected override void OnDesignerViewChanged(EventArgs e)
		{
			if ( _document != null ) {
				if ( this.DesignerViewControl != null )
					this.DesignerViewControl.AddDesignerControl(_document);
				else
					_document.Remove();
			}
			base.OnDesignerViewChanged(e);
		}

		#endregion

		#endregion

		#region Private Members

		#region Variables
		private bool _isInOnRemoved = false;
		private BUSDocumentSymbol _document;
		#endregion

		#region Event Handlers
		private void _document_SizeChanged(object sender, EventArgs e)
		{
			OnDocumentSizeChanged();
		}
		private void _document_Removed(object sender, EventArgs e)
		{
			_document.SizeChanged -= new EventHandler(_document_SizeChanged);
			_document.Removed -= new EventHandler(_document_Removed);
			_document = null;
			if ( !_isInOnRemoved )
				this.Remove();
		}


		#endregion

		#endregion
	}
	#endregion

	public class BUSPublishRoute : BUSRoute
	{
		protected override void Initialize()
		{
			this.Document.IsPublishedDocument = true;
		}
		protected override Point GetDocumentLocation()
		{
			if ( this.Document == null ) {
				return Point.Empty;
			} else {
				this.Document.BringToFront();
				int x = this.EndPoint.X - 16;
				int y = 0;
				if ( this.StartPoint.Y > this.EndPoint.Y )
					y = this.EndPoint.Y - gap - this.Document.Height;
				else
					y = this.EndPoint.Y + gap;

				return new Point(x, y);
			}
		}
		protected override void OnRefreshRoute()
		{
			if ( this.StartControl == null || this.StartControl.DesignerViewControl == null ||
				 this.EndControl == null || this.EndControl.DesignerViewControl == null ) {
				this.Remove();
			}
			Point ptStart, ptEnd;

			this.Points.Clear();
			// add start point
			if ( this.StartConnector != null ) {
				ptStart = this.StartConnector.GetRouteStart(this.StartDockDirection, this);
			} else {
				ptStart = GetDefaultDockPoint(this.StartControl.GetPaintBounds(), this.StartDockDirection);
			}
			// add end point
			if ( this.EndConnector != null ) {
				ptEnd = this.EndConnector.GetRouteEnd(this.EndDockDirection, this);
			} else {
				ptEnd = GetDefaultDockPoint(this.EndControl.GetPaintBounds(), this.EndDockDirection);
			}
			this.Points.Add(ptStart);
			this.Points.Add(new Point(ptStart.X, ptEnd.Y));
			if ( ptStart.X > this.EndControl.Right - cBUSExtend )
				this.EndControl.Width += ( ptStart.X - this.EndControl.Right + cBUSExtend );
			// calculate intermediate route points
			//RecalculateRoutePoints();
			// create GraphicsPath
			GeneratePath();
		}
		protected override void OnRouteCreated()
		{
			//this.StartControl
			while ( this.Document.ContextMenuStrip.Items.Count > 1 ) {
				this.Document.ContextMenuStrip.Items.RemoveAt(1);
			}
			base.OnRouteCreated();
		}
		protected override void OnDocumentSizeChanged()
		{
			if ( this.Document != null )
				this.Document.Location = GetDocumentLocation();
		}
	}

	public class BUSSubscribeRoute : BUSRoute
	{
		protected override void Initialize()
		{
			this.Document.IsPublishedDocument = false;
		}
		protected override Point GetDocumentLocation()
		{
			this.Document.BringToFront();
			int x = this.EndPoint.X - gap - this.Document.Width;
			int y;
			if ( this.StartPoint.Y > this.EndPoint.Y )
				y = this.EndPoint.Y + ( gap << 2 );
			else
				y = this.EndPoint.Y - this.Document.Height - ( gap << 2 );

			return new Point(x, y);
		}
		protected override void OnRefreshRoute()
		{
			Point ptStart, ptEnd;

			this.Points.Clear();
			// add start point
			if ( this.StartConnector != null ) {
				ptStart = this.StartConnector.GetRouteStart(this.StartDockDirection, this);
			} else {
				ptStart = GetDefaultDockPoint(this.StartControl.GetPaintBounds(), this.StartDockDirection);
			}
			// add end point
			if ( this.EndConnector != null ) {
				ptEnd = this.EndConnector.GetRouteEnd(this.EndDockDirection, this);
			} else {
				ptEnd = GetDefaultDockPoint(this.EndControl.GetPaintBounds(), this.EndDockDirection);
			}
			BUSActivitySymbol bas = this.EndControl as BUSActivitySymbol;
			if ( bas != null && bas.IsProcessReply ) {
				this.Points.Add(ptStart);
			} else {
				this.Points.Add(new Point(ptEnd.X, ptStart.Y));
			}
			this.Points.Add(ptEnd);

			if ( ptEnd.X > this.StartControl.Right - cBUSExtend )
				this.StartControl.Width += ( ptEnd.X - this.StartControl.Right + cBUSExtend );

			// calculate intermediate route points
			//RecalculateRoutePoints();
			// create GraphicsPath
			GeneratePath();
		}
		protected override void OnDocumentSizeChanged()
		{
			if ( this.Document != null )
				this.Document.Location = GetDocumentLocation();
		}
		protected override void GeneratePath()
		{
			BUSActivitySymbol bas = this.EndControl as BUSActivitySymbol;
			if ( bas != null && bas.IsProcessReply ) {
			}
			base.GeneratePath();
		}
	}
}
